package com.fa4j.system.app.service.impl;

import com.fa4j.common.base.exception.CommonRequestError;
import com.fa4j.common.base.model.CommonConstants;
import com.fa4j.common.base.model.RemoveCmd;
import com.fa4j.common.base.util.ValidUtil;
import com.fa4j.system.app.convert.AppMenuConverter;
import com.fa4j.system.app.model.*;
import com.fa4j.system.app.repository.AppMenuRepository;
import com.fa4j.system.app.service.AppMenuService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.util.List;
import java.util.Objects;

/**
 * 系统应用菜单 服务接口实现
 *
 * @since 2025-07-14 11:04:33
 */
@Slf4j
@Service
@Validated
@RequiredArgsConstructor
public class AppMenuServiceImpl implements AppMenuService {

    private final AppMenuRepository appMenuRepository;
    private final AppMenuConverter appMenuConverter;

    /**
     * 新增系统应用菜单
     *
     * @param cmd 新增参数
     * @return 系统应用菜单
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AppMenu create(@Valid AppMenuCreateCmd cmd) {
        if (!Objects.equals(cmd.getParentId(), CommonConstants.TREE_ROOT_ID)) {
            AppMenu parent = appMenuRepository.findById(cmd.getParentId())
                    .orElseThrow(() -> CommonRequestError.NOT_FOUND.build("上级菜单"));
            checkAppMenuType(cmd.getType(), parent.getType());
        } else {
            checkAppMenuType(cmd.getType(), null);
        }
        ValidUtil.validInUsed("菜单编码", () -> appMenuRepository.findByAppTypeAndCode(cmd.getAppType(), cmd.getCode()));
        AppMenu entity = appMenuConverter.toEntity(cmd);
        appMenuRepository.create(entity);
        return entity;
    }

    private void checkAppMenuType(AppMenuType type, AppMenuType parentType) {
        if (parentType == null) {
            if (type != AppMenuType.MENU) {
                throw CommonRequestError.BAD_REQUEST.build("一级的类型必须是菜单", null);
            }
        }
        if (parentType == AppMenuType.FUNCTION) {
            throw CommonRequestError.BAD_REQUEST.build("功能类型不能有下级", null);
        }
    }

    /**
     * 编辑系统应用菜单
     *
     * @param cmd 编辑参数
     * @return 系统应用菜单
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AppMenu modify(@Valid AppMenuModifyCmd cmd) {
        AppMenu entity = appMenuRepository.findById(cmd.getId())
                .orElseThrow(() -> CommonRequestError.NOT_FOUND.build("系统应用菜单"));
        appMenuConverter.updateEntity(entity, cmd);
        appMenuRepository.modify(entity);
        return entity;
    }

    /**
     * 删除系统应用菜单
     *
     * @param cmd 删除参数
     * @return 系统应用菜单
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AppMenu remove(@Valid RemoveCmd<Integer> cmd) {
        AppMenu entity = appMenuRepository.findById(cmd.getId())
                .orElseThrow(() -> CommonRequestError.NOT_FOUND.build("系统应用菜单"));

        List<AppMenu> children = appMenuRepository.queryByParentId(cmd.getId());
        if (!children.isEmpty()) {
            throw CommonRequestError.BAD_REQUEST.build("存在下级菜单，不能删除", null);
        }

        entity.setOperatorId(cmd.getOperatorId());
        appMenuRepository.remove(entity);
        return entity;
    }

}




